package com.ucode.application.controller.sys;

import java.util.List;
import java.util.Set;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.ucode.application.form.sys.UserForm;
import com.ucode.application.security.CurrentLoginUserService;
import com.ucode.springboot.starter.web.validator.group.AddGroup;
import com.ucode.springboot.starter.web.validator.group.UpdateGroup;
import com.ucode.sys.model.User;
import com.ucode.sys.service.RoleService;
import com.ucode.sys.service.UserService;
import com.ucode.sys.vo.UserVo;
import com.ucode.tool.base.Paginator;
import com.ucode.tool.base.ResponseResult;
import com.ucode.tool.base.ResultCodeEnum;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

@Api(tags="系统用户管理")
@RestController
@RequestMapping("/sys-user")
@Validated //使用spring的validation
public class UserController {

    private static Log log = LogFactory.get(UserController.class);
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private CurrentLoginUserService currentLoginUserService;
    
    @PreAuthorize("hasAuthority('sys:user:read') or hasRole('ADMIN')")
    @ApiOperation("根据条件分页查询列表")
    @GetMapping(value = "/list")
    public ResponseResult<Object> findPage(
            @ApiParam(value ="姓名")  @RequestParam(value = "realname",required=false) String realname,
            @ApiParam(value ="登录名")  @RequestParam(value = "username",required=false) String username,
            @ApiParam(value ="手机号")  @RequestParam(value = "mobile",required=false) String mobile,
            @ApiParam(value ="部门")  @RequestParam(value = "deptId",required=false) Long deptId,
            @ApiParam(value ="状态")  @RequestParam(value = "statuz",required=false) Integer statuz,
            @ApiParam(value="页码",example="1") @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @ApiParam(value="每页记录数",example="5") @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize){
        
        if(StrUtil.isNotBlank(realname))
            realname = StrUtil.concat(true,realname, "%");
        if(StrUtil.isNotBlank(username))
            username = StrUtil.concat(true,username, "%");
        if(StrUtil.isNotBlank(mobile))
            mobile = StrUtil.concat(true,mobile, "%");
        
        Paginator<UserVo> page = userService.queryPage(realname, username, mobile, deptId, statuz, pageNum, pageSize);
        return ResponseResult.success(page);
    }
    
    @PreAuthorize("hasAuthority('sys:user:read') or hasRole('ADMIN')")
    @ApiOperation(value="根据主键查询")
    @ApiImplicitParam(name = "id", value = "主键ID", required = true, dataType = "String",paramType = "path")
    @GetMapping("/getById/{id}")
    public ResponseResult<Object> getById(@PathVariable(name="id",required=true) Long id){
        
        User user = userService.findById(id);
        user.setPassword(null);//把密码屏蔽掉,不返回给前端
        return ResponseResult.success(user);
    }
    
    @ApiOperation(value="根据用户名查询用户")
    @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String",paramType = "path")
    @GetMapping("/getByUsername/{username}")
    public ResponseResult<Object> getByUsername(@PathVariable(name="username",required=true) String username){
        User user = userService.findByUsername(username);
        user.setPassword(null);//把密码屏蔽掉,不返回给前端
        return ResponseResult.success(user);
    }
    
    @ApiOperation(value="根据手机号查询用户")
    @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String",paramType = "path")
    @GetMapping("/getByMobile/{mobile}")
    public ResponseResult<Object> getByMobile(@PathVariable(name="mobile",required=true) String mobile){
        User user = userService.findByMobile(mobile);
        user.setPassword(null);//把密码屏蔽掉,不返回给前端
        return ResponseResult.success(user);
    }
    
    @ApiOperation(value="根据邮箱查询用户")
    @ApiImplicitParam(name = "email", value = "邮箱", required = true, dataType = "String",paramType = "path")
    @GetMapping("/getByEmail/{email}")
    public ResponseResult<Object> getByEmail(@PathVariable(name="email",required=true) String email){
        User user = userService.findByEmail(email);
        user.setPassword(null);//把密码屏蔽掉,不返回给前端
        return ResponseResult.success(user);
    }
    
    @PreAuthorize("hasAuthority('sys:user:write') or hasRole('ADMIN')")
    @ApiOperation(value="创建")
    @PostMapping("/create")
    public ResponseResult<Object> create(@Validated({AddGroup.class}) @RequestBody UserForm form) {
        
        User user = new User(form.getUsername(), form.getPassword(), form.getRealname(), form.getHeadImg(), form.getMobile(), form.getEmail(), form.getNum(), form.getSex(), form.getStatuz(), form.getDeptId(), form.getJob(), form.getParentId(), null, null);
        List<Long> roleIds = form.getRoleIds();
        user = userService.insert(user);
        if(user != null && CollUtil.isNotEmpty(roleIds)){
            roleService.relatedUserRoles(user.getId(), roleIds);
        }
        
        return user != null ? ResponseResult.success(user) : ResponseResult.failed();
    }
    
    @PreAuthorize("hasAuthority('sys:user:write') or hasRole('ADMIN')")
    @ApiOperation(value="更新")
    @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String",paramType = "path")
    @PostMapping("/update/{id}")
    public ResponseResult<Object> update(@PathVariable(name="id",required=true) Long id,
            @Validated({UpdateGroup.class}) @RequestBody UserForm form) {
        
        User user = new User(form.getUsername(), form.getPassword(), form.getRealname(), form.getHeadImg(), form.getMobile(), form.getEmail(), form.getNum(), form.getSex(), form.getStatuz(), form.getDeptId(), form.getJob(), form.getParentId(), null, null);
        user.setId(id);
        List<Long> roleIds = form.getRoleIds();
        int i = userService.update(user);
        if(i > 0 && CollUtil.isNotEmpty(roleIds)){
            roleService.relatedUserRoles(user.getId(), roleIds);
        }
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
        
    }
    
    @PreAuthorize("hasAuthority('sys:user:write') or hasRole('ADMIN')")
    @ApiOperation(value="更新状态")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userIds", value = "用户列表(最多100人,用逗号隔开)", required = true, paramType = "query"),
        @ApiImplicitParam(name = "statuz", value = "状态:0禁用1激活", required = true, dataType = "String", paramType = "query"),
    })
    @PostMapping("/updateStatuz")
    public ResponseResult<Object> update(
            @Size(min=1,max = 100,message="一次最多选择100条") @RequestParam(value = "userIds",required = true)List<Long> userIds,
            @RequestParam(value = "statuz",required = true)Integer statuz){
        userService.updateStatuz(userIds, statuz);
        return ResponseResult.success();
    }
    
    @PreAuthorize("hasAuthority('sys:user:write') or hasRole('ADMIN')")
    @ApiOperation(value="重置账号")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String",paramType = "path"),
        @ApiImplicitParam(name = "username", value = "新登录名", required = true, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "password", value = "新密码", required = true, dataType = "String", paramType = "query"),
    })
    @PostMapping("/resetUsername/{id}")
    public ResponseResult<Object> resetUsername(@PathVariable(name="id",required=true) Long id,
            @Length(max=50,message = "用户名最长50字符") @RequestParam(value = "username",required = true) String username,
            @Pattern(regexp = "^[\\w_-]{6,16}$",message = "密码长度6-16,可由大小写字母、数字、下划线 和减号组成") @RequestParam(value = "password",required = true)String password){
        userService.resetUsername(id, username, password);
        return ResponseResult.success();
    }
    
    @PreAuthorize("hasAuthority('sys:user:write') or hasRole('ADMIN')")
    @ApiOperation(value="重置密码")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userIds", value = "用户列表(最多100人,用逗号隔开)", required = true, paramType = "query"),
        @ApiImplicitParam(name = "password", value = "新密码", required = true, dataType = "String", paramType = "query"),
    })
    @PostMapping("/resetPassword")
    public ResponseResult<Object> resetPsw(
            @Size(min=1,max = 100,message="一次最多选择100条") @RequestParam(value = "userIds",required = true)List<Long> userIds,
            @Pattern(regexp = "^[\\w_-]{6,16}$",message = "密码长度6-16,可由大小写字母、数字、下划线 和减号组成") @RequestParam(value = "password",required = true)String password){
        
        userService.updatePassword(userIds, password);
        return ResponseResult.success();
    }
    
    @ApiOperation(value="当前用户修改密码")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "oldPassword", value = "原密码", required = true, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "password", value = "新密码", required = true, dataType = "String", paramType = "query"),
    })
    @PostMapping("/current/updatePassword")
    public ResponseResult<Object> updatePsw(
            @RequestParam(value = "oldPassword",required = true)String oldPassword,
            @Pattern(regexp = "^[\\w_-]{6,16}$",message = "密码长度6-16,可由大小写字母、数字、下划线 和减号组成") @RequestParam(value = "password",required = true)String password){
        
        Long userId = currentLoginUserService.getCurrentUserId();
        User user = userService.findById(userId);
        if(!oldPassword.equals(user.getPassword())){
            return ResponseResult.result(ResultCodeEnum.LOGIN_ERROR);
        }
        int i = userService.updatePassword(userId, password);
        return i>0?ResponseResult.success():ResponseResult.failed();
    }
    
    @ApiOperation(value="当前用户信息")
    @GetMapping("/current")
    public ResponseResult<Object> currentUser(){
        
//        log.info("测试优雅停机>>>>模拟业务处理1分钟,开始...");
//        Long serverTime = System.currentTimeMillis();
//        while (System.currentTimeMillis() < serverTime + (60 * 1000)){
//            log.info("正在处理业务，当前时间：{}，开始时间：{}", System.currentTimeMillis(), serverTime);
//        }
//        log.info("测试优雅停机>>>>模拟业务处理1分钟,结束...");
//        log.info("测试优雅停机>>>>模拟业务处理1分钟,结束..."+(currentLoginUserService== null));
        
        User user = currentLoginUserService.getCurrentUser();
        return ResponseResult.success(user);
    }
    
    @ApiOperation(value="当前用户权限信息")
    @GetMapping("/current/permissions")
    public ResponseResult<Object> currentUserPermissions(){
        Set<String> permissions = currentLoginUserService.getCurrentUserRoles();
        return ResponseResult.success(permissions);
    }
    
}
